use crate::semantic_analysis::type_checker::*;
use crate::{ast_define::algebraic_expr::*, semantic_analysis::Type};

impl super::TypeChecker {
    /// 检查表达式，返回表达式的类型
    pub fn check_exp(&mut self, exp: &Exp) -> Option<Type> {
        let type_of_exp = self.check_add_exp(&exp.add_exp);
        debug!("\ntype_of_exp: {:#?}", type_of_exp);
        type_of_exp
    }

    /// 检查加法表达式
    pub fn check_add_exp(&mut self, add_exp: &AddExp) -> Option<Type> {
        match add_exp {
            AddExp::LinearOperator_MulExp(linear_mul) => self.check_mul_exp(&linear_mul.mul_exp),
            AddExp::MulExp_AddExpRecursiveMove(mul_recursive) => {
                // 检查左侧乘法表达式
                let left_type = self.check_mul_exp(&mul_recursive.mul_exp);

                // 检查右侧的递归部分
                if let Some(recursive_move) = &mul_recursive.add_exp_recursive_move {
                    self.check_add_exp_recursive_move(recursive_move);
                }

                // 加法表达式的结果类型总是Int
                // if left_type.is_some() {
                //     Some(Type::Int)
                // } else {
                //     None
                // }
                left_type
            }
        }
    }

    /// 检查加法表达式的递归部分
    pub fn check_add_exp_recursive_move(&mut self, recursive_move: &AddExpRecursiveMove) {
        // 检查右侧操作数
        let right_type = self.check_mul_exp(&recursive_move.mul_exp);

        // 检查操作数类型 - 加法运算符要求操作数为int类型
        if let Some(right_type) = right_type
            && right_type != Type::Int
        {
            self.errors
                .push(SemanticError::type_mismatched_for_operands(
                    recursive_move.meta_info.clone(),
                ));
        }

        // 递归检查后续部分
        if let Some(next_move) = recursive_move.add_exp_recursive_move.as_ref() {
            self.check_add_exp_recursive_move(next_move);
        }
    }

    /// 检查乘法表达式
    pub fn check_mul_exp(&mut self, mul_exp: &MulExp) -> Option<Type> {
        match mul_exp {
            MulExp::ExponentOperator_UnaryExp(exp_unary) => {
                self.check_unary_exp(&exp_unary.unary_exp)
            }
            MulExp::UnaryExp_MulExpRecursiveMove(unary_recursive) => {
                // 检查左侧一元表达式
                let left_type = self.check_unary_exp(&unary_recursive.unary_exp);

                // 检查右侧的递归部分
                if let Some(recursive_move) = &unary_recursive.mul_exp_recursive_move {
                    self.check_mul_exp_recursive_move(recursive_move);
                }

                // 乘法表达式的结果类型总是Int
                // if left_type.is_some() {
                //     Some(Type::Int)
                // } else {
                //     None
                // }
                left_type
            }
        }
    }

    /// 检查乘法表达式的递归部分
    pub fn check_mul_exp_recursive_move(&mut self, recursive_move: &MulExpRecursiveMove) {
        // 检查右侧操作数
        let right_type = self.check_unary_exp(&recursive_move.unary_exp);

        // 检查操作数类型 - 乘法运算符要求操作数为int类型
        if let Some(right_type) = right_type
            && right_type != Type::Int
        {
            self.errors
                .push(SemanticError::type_mismatched_for_operands(
                    recursive_move.meta_info.clone(),
                ));
        }

        // 递归检查后续部分
        if let Some(next_move) = recursive_move.mul_exp_recursive_move.as_ref() {
            self.check_mul_exp_recursive_move(next_move);
        }
    }

    /// 检查一元表达式
    pub fn check_unary_exp(&mut self, unary_exp: &UnaryExp) -> Option<Type> {
        match unary_exp {
            UnaryExp::UnaryOperator_UnaryExp(unary_op) => {
                // 检查操作数
                let operand_type = self.check_unary_exp(&unary_op.unary_exp);

                // 一元运算符要求操作数为int类型
                if let Some(operand_type) = operand_type
                    && operand_type != Type::Int
                {
                    self.errors
                        .push(SemanticError::type_mismatched_for_operands(
                            unary_op.meta_info.clone(),
                        ));
                    return None;
                }

                Some(Type::Int)
            }
            UnaryExp::Ident_FuncRParams(func_call) => self.check_function_call(func_call),
            UnaryExp::PrimaryExp(primary) => self.check_primary_exp(primary),
        }
    }

    /// 检查基本表达式
    pub fn check_primary_exp(&mut self, primary_exp: &PrimaryExp) -> Option<Type> {
        match primary_exp {
            PrimaryExp::Exp_Parenthesis_Wrapper(wrapper) => self.check_exp(&wrapper.exp),
            PrimaryExp::Number(_) => Some(Type::Int),
            PrimaryExp::LVal(lval) => {
                self.check_lval(lval, false) // false表示这不是赋值的左侧
            }
        }
    }

    /// 检查函数调用
    pub fn check_function_call(&mut self, func_call: &Ident_FuncRParams) -> Option<Type> {
        let (expected_params, return_type) = match self.symbol_table.lookup(&func_call.ident.value)
        {
            Some(symbol) => match &symbol.symbol_type {
                SymbolType::Function(Type::Function {
                    params,
                    return_type,
                }) => (params.clone(), return_type.clone()),
                _ => {
                    // 符号的类型不是函数
                    self.errors.push(SemanticError::not_a_function(
                        &func_call.ident.value,
                        func_call.ident.meta_info.clone(),
                    ));
                    return None;
                }
            },
            None => {
                // 函数未定义
                self.errors.push(SemanticError::undefined_function(
                    &func_call.ident.value,
                    func_call.ident.meta_info.clone(),
                ));
                return None;
            }
        };

        // 检查参数
        let mut actual_param_types = Vec::new();
        if let Some(params) = func_call.func_r_params.as_ref() {
            for param in &params.exps {
                if let Some(param_type) = self.check_exp(param) {
                    actual_param_types.push(param_type);
                }
            }
        }
        debug!(
            "\nactual_param_types: {:?}\nexpected_params:\n{:#?}",
            actual_param_types, expected_params
        );

        // 检查参数数量
        if actual_param_types.len() != expected_params.len() {
            self.errors
                .push(SemanticError::function_not_applicable_for_arguments(
                    func_call.meta_info.clone(),
                ));
            return None;
        }

        // 检查参数类型匹配
        for (actual, expected) in actual_param_types.iter().zip(expected_params.iter()) {
            if !expected.symbol_type.get_type().is_assignable_from(actual) {
                self.errors
                    .push(SemanticError::function_not_applicable_for_arguments(
                        func_call.meta_info.clone(),
                    ));
                return None;
            }
        }

        Some(*return_type)
    }

    /// 检查条件表达式
    pub fn check_cond(&mut self, cond: &Cond) -> Option<Type> {
        self.check_lor_exp(&cond.l_or_exp)
    }

    /// 检查逻辑或表达式
    pub fn check_lor_exp(&mut self, lor_exp: &LOrExp) -> Option<Type> {
        match lor_exp {
            LOrExp::OR_LAndExp(or_land) => self.check_land_exp(&or_land.l_and_exp),
            LOrExp::LAndExp_LOrExpRecursiveMove(land_recursive) => {
                // 检查左侧逻辑与表达式
                let left_type = self.check_land_exp(&land_recursive.l_and_exp);

                // 检查右侧的递归部分
                if let Some(recursive_move) = &land_recursive.l_or_exp_recursive_move {
                    self.check_lor_exp_recursive_move(recursive_move);
                }

                // 逻辑或表达式的结果类型总是Int (在SysY中，布尔值用int表示)
                if left_type.is_some() {
                    Some(Type::Int)
                } else {
                    None
                }
            }
        }
    }

    /// 检查逻辑或表达式的递归部分
    pub fn check_lor_exp_recursive_move(&mut self, recursive_move: &LOrExpRecursiveMove) {
        // 检查右侧操作数
        self.check_land_exp(&recursive_move.l_and_exp);

        // 递归检查后续部分
        if let Some(next_move) = recursive_move.l_or_exp_recursive_move.as_ref() {
            self.check_lor_exp_recursive_move(next_move);
        }
    }

    /// 检查逻辑与表达式
    pub fn check_land_exp(&mut self, land_exp: &LAndExp) -> Option<Type> {
        match land_exp {
            LAndExp::AND_EqExp(and_eq) => self.check_eq_exp(&and_eq.eq_exp),
            LAndExp::EqExp_LAndExpRecursiveMove(eq_recursive) => {
                // 检查左侧相等表达式
                let left_type = self.check_eq_exp(&eq_recursive.eq_exp);

                // 检查右侧的递归部分
                if let Some(recursive_move) = &eq_recursive.l_and_exp_recursive_move {
                    self.check_land_exp_recursive_move(recursive_move);
                }

                // 逻辑与表达式的结果类型总是Int
                if left_type.is_some() {
                    Some(Type::Int)
                } else {
                    None
                }
            }
        }
    }

    /// 检查逻辑与表达式的递归部分
    pub fn check_land_exp_recursive_move(&mut self, recursive_move: &LAndExpRecursiveMove) {
        // 检查右侧操作数
        self.check_eq_exp(&recursive_move.eq_exp);

        // 递归检查后续部分
        if let Some(next_move) = recursive_move.l_and_exp_recursive_move.as_ref() {
            self.check_land_exp_recursive_move(next_move);
        }
    }

    /// 检查相等表达式
    pub fn check_eq_exp(&mut self, eq_exp: &EqExp) -> Option<Type> {
        match eq_exp {
            EqExp::EqualityOperator_RelExp(eq_rel) => self.check_rel_exp(&eq_rel.rel_exp),
            EqExp::RelExp_EqExpRecursiveMove(rel_recursive) => {
                // 检查左侧关系表达式
                let left_type = self.check_rel_exp(&rel_recursive.rel_exp);

                // 检查右侧的递归部分
                if let Some(recursive_move) = &rel_recursive.eq_exp_recursive_move {
                    self.check_eq_exp_recursive_move(recursive_move);
                }

                // 相等表达式的结果类型总是Int
                if left_type.is_some() {
                    Some(Type::Int)
                } else {
                    None
                }
            }
        }
    }

    /// 检查相等表达式的递归部分
    pub fn check_eq_exp_recursive_move(&mut self, recursive_move: &EqExpRecursiveMove) {
        // 检查右侧操作数
        self.check_rel_exp(&recursive_move.rel_exp);

        // 递归检查后续部分
        if let Some(next_move) = recursive_move.eq_exp_recursive_move.as_ref() {
            self.check_eq_exp_recursive_move(next_move);
        }
    }

    /// 检查关系表达式
    pub fn check_rel_exp(&mut self, rel_exp: &RelExp) -> Option<Type> {
        match rel_exp {
            RelExp::RelationOperator_AddExp(rel_add) => self.check_add_exp(&rel_add.add_exp),
            RelExp::AddExp_RelExpRecursiveMove(add_recursive) => {
                // 检查左侧加法表达式
                let left_type = self.check_add_exp(&add_recursive.add_exp);

                // 检查右侧的递归部分
                if let Some(recursive_move) = &add_recursive.rel_exp_recursive_move {
                    self.check_rel_exp_recursive_move(recursive_move);
                }

                // 关系表达式的结果类型总是Int
                if left_type.is_some() {
                    Some(Type::Int)
                } else {
                    None
                }
            }
        }
    }

    /// 检查关系表达式的递归部分
    pub fn check_rel_exp_recursive_move(&mut self, recursive_move: &RelExpRecursiveMove) {
        // 检查右侧操作数 - 关系运算符要求操作数为int类型
        let right_type = self.check_add_exp(&recursive_move.add_exp);

        if let Some(right_type) = right_type
            && right_type != Type::Int
        {
            self.errors
                .push(SemanticError::type_mismatched_for_operands(
                    recursive_move.meta_info.clone(),
                ));
        }

        // 递归检查后续部分
        if let Some(next_move) = recursive_move.rel_exp_recursive_move.as_ref() {
            self.check_rel_exp_recursive_move(next_move);
        }
    }

    pub fn exp_is_single_var(self, exp: &Exp) -> Option<&LVal> {
        let Exp { add_exp, .. } = exp;
        if let AddExp::MulExp_AddExpRecursiveMove(this) = add_exp
            && let None = this.add_exp_recursive_move
            && let MulExp::UnaryExp_MulExpRecursiveMove(ref this) = *this.mul_exp
            && let None = this.mul_exp_recursive_move
            && let UnaryExp::PrimaryExp(ref this) = this.unary_exp
            && let PrimaryExp::LVal(this) = this
        {
            return Some(this);
        }

        None
    }

    pub fn exp_is_func_call(self, exp: &Exp) -> Option<&Ident_FuncRParams> {
        let Exp { add_exp, .. } = exp;
        if let AddExp::MulExp_AddExpRecursiveMove(this) = add_exp
            && let None = this.add_exp_recursive_move
            && let MulExp::UnaryExp_MulExpRecursiveMove(ref this) = *this.mul_exp
            && let None = this.mul_exp_recursive_move
            && let UnaryExp::Ident_FuncRParams(ref this) = this.unary_exp
        {
            return Some(this);
        }

        None
    }
}
